/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package model;

import com.google.inject.Inject;
import com.google.inject.Injector;
import exception.InvalidCommandException;
import exception.InvalidCommandResultReferenceException;
import java.util.LinkedList;
import java.util.Queue;

/**
 *
 * @author think
 */
public class PipeLineCommand implements Executable {

    private Queue<String> commands = new LinkedList<String>();
    private VMMachine machine;
//    private String output = "";
//    private int result = -1;
    private CommandResult result;
    private String command;
    private TSM scriptManager;
    private CommandResultManager resultManager;
    private Injector injector;

    @Inject
    public PipeLineCommand(TSM scriptManager, CommandResultManager resultManager, Injector injector) {
        this.scriptManager = scriptManager;
        this.resultManager = resultManager;
        this.injector = injector;
//        this.command = cmd;
    }

    public void setInjector(Injector injector){
        this.injector = injector;
    }

    public void setCmd(String cmd) {
        this.command = cmd;
        String[] cmds = cmd.split("\\|");
        for (int i = 0; i < cmds.length; i++) {
            commands.add(cmds[i].trim());
        }
//        this.command = cmd;
    }

    public String getCmd() {
        return this.command;
    }

//    @Inject
//    public PipeLineCommand(TestScriptManager scriptManager, CommandResultManager resultManager, String cmd) {
//        this.resultManager = resultManager;
//        this.scriptManager = scriptManager;
//        this.command = cmd;
//        String[] cmds = cmd.split("\\|");
//        for (int i = 0; i < cmds.length; i++) {
//            commands.add(cmds[i].trim());
//        }
//    }
    public void run() {
        try {
            String firstCmdStr = commands.poll();
            System.out.println("this first command is: " + firstCmdStr);

//            Command firstCmd = Guice.createInjector(new CommandModule(firstCmdStr)).getInstance(Command.class);
            Command firstCmd;
            if (this.injector == null) {
                System.out.println("oooooooooooops, you can't fuck around the injector");
            }
            firstCmd = this.injector.getInstance(Command.class);
            firstCmd.setCmd(firstCmdStr);

            firstCmd.runTillFinish();
            if (firstCmd.getResult().getRc() > 0) {
                this.setResult(firstCmd.getResult());
//                this.output = firstCmd.getOutput();
//                this.result = firstCmd.getResult();
            } else {
                String result = firstCmd.getOutput();
                while (commands.size() > 0) {
                    String cmd = commands.poll();

//                    Command currentCmd = Guice.createInjector(new CommandModule(cmd + " " + result)).getInstance(Command.class);
                    Command currentCmd = this.injector.getInstance(Command.class);
                    currentCmd.setCmd(cmd + " " + result);

                    currentCmd.runTillFinish();
                    this.setResult(currentCmd.getResult());
//                    this.output = currentCmd.getOutput();
//                    this.result = currentCmd.getResult();
                    if (this.result.getRc() > 0) {
                        break;
                    }
                }
            }
//            this.result = 0;
//            this.output = "Composite command finished";
        } catch (InvalidCommandException ex) {
            this.setResult(new CommandResult(1, ex.getMessage()));
        } catch (InvalidCommandResultReferenceException ex) {
            this.setResult(new CommandResult(1, ex.getMessage()));
        } catch (InterruptedException e){
            this.setResult(new CommandResult(1, e.getMessage()));
        }
    }

    public VMMachine getMachine() {
        return this.machine;
    }

    public void setResult(CommandResult result) {
        this.result = result;
    }

    public boolean isSucceed() {
        return this.result.isSucceed();
    }

    public boolean finished() {
        return this.result.getRc() >= 0;
    }

    public CommandResult getResult() {
        return this.result;
    }
}
